package com.zjw.forum.controller;

import com.sun.istack.internal.NotNull;
import com.zjw.forum.common.AppResult;
import com.zjw.forum.common.ResultCode;
import com.zjw.forum.config.AppConfig;
import com.zjw.forum.dao.UserMapper;
import com.zjw.forum.exception.ApplicationException;
import com.zjw.forum.model.User;
import com.zjw.forum.services.IUserService;
import com.zjw.forum.utils.JWTUtil;
import com.zjw.forum.utils.MD5Util;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;

@Api("用户接口")
@Slf4j
@RequestMapping("/user")
@RestController
public class UserController {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private IUserService userService;
    /**
     * 注册用户
     * @param username 用户名
     * @param nickname 昵称
     * @param password 密码
     * @param passwordRepeat 确认密码
     * @return
     */
    @ApiOperation("注册账号")
    @PostMapping("/register")
    public AppResult registerUser(@RequestParam("username") @ApiParam("用户名") @NotNull String username,
                                  @RequestParam("nickname") @ApiParam("昵称") @NotNull String nickname,
                                  @RequestParam("password") @ApiParam("密码") @NotNull String password,
                                  @RequestParam("passwordRepeat") @ApiParam("确认密码") @NotNull String passwordRepeat)
    {
        //判断密码和确认密码是否相同
        if(!password.equals(passwordRepeat)){
            //两次密码输入不相同
            //打印日志
            log.info(ResultCode.FAILED_TWO_PWD_NOT_SAME.getMessage());
            //不抛异常，直接返回错误信息即可
            return AppResult.failed(ResultCode.FAILED_TWO_PWD_NOT_SAME);
        }
        //对密码进行加密
        String enPassword = MD5Util.md5SaltEncryption(password);
        //创建User对象，赋值传给Service
        User user=new User();
        user.setPassword(enPassword);
        user.setNickname(nickname);
        user.setUsername(username);
        //调用service
        userService.createNormalUser(user);
        log.info("用户注册成功. username = " + user.getUsername() + ". ");
        return AppResult.success("注册成功");
    }

//    /**
//     * 登陆验证 使用session
//     * @param username
//     * @param password
//     * @return
//     */
//    @ApiOperation("登陆接口")
//    @PostMapping("/login")
//    public AppResult loginUser(HttpServletRequest request,
//                               @RequestParam("username") @NotNull @ApiParam("用户名") String username,
//                               @RequestParam("password") @NotNull @ApiParam("密码") String password){
//        User user=userService.loginNromalUser(username,password);
//        //有时候后端的service controller是不同人开发的，为了健壮性可以再检查一下user
//        if(user==null){
//            log.info(ResultCode.ERROR_SERVICES.getMessage());
//            return AppResult.failed(ResultCode.ERROR_SERVICES);
//        }
//        //将用户信息存入session
//        HttpSession session = request.getSession(true);
//        session.setAttribute(AppConfig.USER_SESSION,user);
//        log.info("用户登陆成功. username = " + user.getUsername() + ". ");
//        return AppResult.success("登陆成功");
//    }
//
//
//    @ApiOperation("获取用户信息")
//    @GetMapping("/info")
//    public AppResult getUserInfo(HttpServletRequest request,
//                                 @RequestParam(value = "id",required = false) @ApiParam("用户id") Long id){
//        User user;
//        if(id==null){
//            //不自动创建session
//            HttpSession session=request.getSession(false);
//            //需要对前端携带的session进行判断
//            if(session==null||session.getAttribute(AppConfig.USER_SESSION)==null){
//                //请求没有携带session（用户未登录）||session是造假的匹配的session对象没有存储user
//                log.warn(ResultCode.FAILED_FORBIDDEN.getMessage());
//                return AppResult.failed(ResultCode.FAILED_FORBIDDEN);
//            }
//            //当前用户，从session中获取user
//            user=(User)session.getAttribute(AppConfig.USER_SESSION);
//        }else{
//            //其他用户
//            user = userService.getUserinfo(id);
//            //判断user
//            if(user==null){
//                log.warn(ResultCode.ERROR_SERVICES.getMessage());
//                return AppResult.failed(ResultCode.ERROR_SERVICES);
//            }
//        }
//        return AppResult.success(user);
//    }

    /**
     * 登陆验证  使用令牌
     * @param username
     * @param password
     * @return
     */
    @ApiOperation("登陆接口")
    @PostMapping("/login")
    public AppResult loginUser(@RequestParam("username") @NotNull @ApiParam("用户名") String username,
                               @RequestParam("password") @NotNull @ApiParam("密码") String password){
        User user=userService.loginNromalUser(username,password);
        //有时候后端的service controller是不同人开发的，为了健壮性可以再检查一下user
        if(user==null){
            log.info(ResultCode.ERROR_SERVICES.getMessage());
            return AppResult.failed(ResultCode.ERROR_SERVICES);
        }
        //发送令牌给客户端
        String token = JWTUtil.genToken(AppConfig.USER_SESSION, user);
        log.info("token: "+token);
        log.info("用户登陆成功. username = " + user.getUsername() + ". ");
        return AppResult.success("登陆成功",token);
    }

    /**
     * 获取用户信息 令牌实现
     * @param request
     * @param id
     * @return
     */
    @ApiOperation("获取用户信息")
    @GetMapping("/info")
    public AppResult getUserInfo(HttpServletRequest request,
                                 @RequestParam(value = "id",required = false) @ApiParam("用户id") Long id){
        User user;
        if(id==null){
            String user_token = request.getHeader("user_token");
            user = JWTUtil.getUserFromToken(user_token);
            if(user==null){
                //令牌不合法
                log.error(ResultCode.FAILED_TOKEN.getMessage());
                return AppResult.failed(ResultCode.FAILED_TOKEN);
            }
        }else{
            //其他用户
            user = userService.getUserinfo(id);
            //判断user
            if(user==null){
                log.warn(ResultCode.ERROR_SERVICES.getMessage());
                return AppResult.failed(ResultCode.ERROR_SERVICES);
            }
        }
        return AppResult.success(user);
    }

    @ApiOperation("修改用户信息")
    @PostMapping("/modifyInfo")
    public ResponseEntity<AppResult<User>> modifyInfo(
            HttpServletRequest request,
            @RequestParam(value = "nickName", required = false) @ApiParam("用户昵称") String nickName,
            @RequestParam(value = "email", required = false) @ApiParam("邮箱") String email,
            @RequestParam(value = "phoneNum", required = false) @ApiParam("电话号码") String phoneNum,
            @RequestParam(value = "remark", required = false) @ApiParam("个人简介") String remark) {
        String user_token = request.getHeader("user_token");
        log.info("user_token: {}"+user_token);
        User user = JWTUtil.getUserFromToken(user_token);
        if (user == null) {
            log.error(ResultCode.FAILED_TOKEN.getMessage());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_TOKEN));
        }
        User user1 = new User();
        user1.setId(user.getId());
        user1.setEmail(email);
        user1.setPhoneNum(phoneNum);
        user1.setRemark(remark);
        user1.setNickname(nickName);

        // 更新用户信息
        User user2 = userService.updateUserInfo(user1);
        log.info("用户信息更新成功: {}", user2);

        //查询最新的用户信息存入令牌中
        User user_Token = userService.getUserinfo(user2.getId());
        // 生成新令牌
        String user_token1 = JWTUtil.genToken(AppConfig.USER_SESSION, user_Token); // 确保参数正确
        log.info("生成的 user-token: {}", user_token1);

        // 设置响应头
        HttpHeaders headers = new HttpHeaders();
        headers.add("user-token", user_token1);
        return new ResponseEntity<>(AppResult.success(user2), headers, HttpStatus.OK);
    }
    @PostMapping("/modifyPwd")
    public AppResult modifyPassword(
            HttpServletRequest request,
            @RequestParam(value = "oldPassword") @ApiParam("旧密码") @NotNull String oldPassword,
            @RequestParam(value = "newPassword") @ApiParam("新密码") @NotNull String newPassword,
            @RequestParam(value = "passwordRepeat") @ApiParam("确认密码") @NotNull String passwordRepeat){
        //查询两次输入的密码是否相同
        if(!newPassword.equals(passwordRepeat)){
            log.error(ResultCode.FAILED_TWO_PWD_NOT_SAME.getMessage());
            return AppResult.failed(ResultCode.FAILED_TWO_PWD_NOT_SAME);
        }
        //获取登陆用户
        String user_token = request.getHeader("user_token");
        log.info("user_token: {}"+user_token);
        User user = JWTUtil.getUserFromToken(user_token);
        if (user == null) {
            log.error(ResultCode.FAILED_TOKEN.getMessage());
            return AppResult.failed(ResultCode.FAILED_TOKEN);
        }
        //校验用户是否存在
        if(userService.getUserinfo(user.getId())==null){
            log.error(ResultCode.FAILED_USER_NOT_EXISTS.getMessage());
            return AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS);
        }
        //由于令牌没有存储密码，所以得从数据库中获取
        String strPassword = userMapper.selectPasswordById(user.getId());
        log.info("数据库中获取的密码："+strPassword);
        //查询用户的旧密码，进行校验
        //数据库存储的密码是加密过后的,要对oldPassword进行加密再比较
        if(!MD5Util.md5SaltVerify(oldPassword,strPassword)){
            //密码不相同
            log.error(ResultCode.FAILED_PWD.getMessage());
            return AppResult.failed(ResultCode.FAILED_PWD);
        }
        //修改密码
        int i = userService.updatePassword(user.getId(), newPassword);
        if(i!=1){
            log.warn(ResultCode.FAILED.getMessage());
            return AppResult.failed(ResultCode.FAILED);
        }
        //前端把令牌删了
        return AppResult.success();
    }
}
